/*
 * @Description: uav 无人机实例入口文件
 * @Date: 2022-01-06 11:39:31
 * @Author: yeming
 */

/* eslint-disable no-undef */
/* eslint-disable array-bracket-spacing */
/* eslint-disable space-before-function-paren */

// 将坐标从源投影转换为目标投影
// 1、EPSG:4326(WGS84) 地理坐标系统(三维：由经度、纬度和高度组成)
// 2、EPSG:3857 投影坐标系 (二维：基于墨卡托投影，把 WGS84坐标系投影到正方形)
// 3、经纬度如：[116.274005, 40.046237, 500]为地理坐标系，投影坐标系如：[12493831.729692265, 4210864.666386095, 100]，由EPSG_4326 => EPSG_3857
// transform 将坐标从源投影转换为目标投影。这将返回一个新坐标（并且不会修改原始坐标）。
// fromLonLat 将坐标从经度/纬度转换为不同的投影坐标。 transform(latlng, "EPSG:4326", "EPSG:3857")
// toLonLat 将投影坐标转换为经度/纬度。 transform(coordinate, "EPSG:3857", "EPSG:4326")

import OlOverlay from 'ol/Overlay'
import { transform, fromLonLat, toLonLat } from 'ol/proj.js'

import { setLiveUavSvg, elementStr2Node } from '../common/svg.js'
import { MAP_TYPE, getMapType, setMapType } from '../../common/mapType.js'
import { UAV, setUavActiveSessionId, getUavActiveSessionId, setUavLocked, getUavLocked, setPodLocked, getPodLocked } from '../../common/uav.js'
import { removeFeatureAndDeleteHashMap, removeAllFeatureAndDeleteHashMap } from '../common/removeFeature.js'

import { Point, Point3d } from '../model/point.js'
import { Line, Line3d } from '../model/line/line.js'
import { Circle, Circle3d } from '../model/circle.js'

const EPSG_4326 = 'EPSG:4326' // 地理坐标系(WGS84)
const EPSG_3857 = 'EPSG:3857' // 投影坐标系(UTM)
const EPSG_4326_LATLNG = [116, 40, 80] // 默认经纬度（北京）
const HPR = [0, 0, 0] // 默认hpr
const UAV_POD_VIEW = './static/olcsMap/img/pod_point.png'
const DYNAMIC_TRACK_LINE_LENGTH = 1024 // java过来的动态航迹总长度
const UAV3D_GLTF_JSON = './static/uavmodle/cesium-3C2.json'

class Uav3d {
  constructor(entities, uav2dSessionId, options) {
    this.entities = entities
    // 3D模型在Cesium中被描述为名为Cesium.Entity的实体类，可以通过这个类加载gltf的3D模型数据。
    // 而地球显示组件Cesium.Viewer存在一个成员变量entities，它就是Cesium.Entity的集合类，提供了add函数接口
    this.entity = this.entities.add({
      id: options.sessionId || uav2dSessionId, // 创建和2d飞机相同sn的entity,
      name: 'uav3d.gltf',
      show: true,
      // position: position,
      // orientation: orientation,
      model: {
        uri: UAV3D_GLTF_JSON,
        minimumPixelSize: 128,
        maximumScale: 200,
        color: Cesium.Color.WHITE,
        colorBlendMode: Cesium.ColorBlendMode.HIGHLIGHT,
        colorBlendAmount: 1,
        silhouetteColor: Cesium.Color.BLACK,
        silhouetteSize: 2
      }
    })
  }
}

class Uav {
  constructor(ol2d, ol3d, uavMap, uavSource) {
    this.ol2d = ol2d
    this.ol3d = ol3d
    this.map2d = ol2d.map2d
    this.map3d = ol3d.map3d
    this.scene = ol3d.scene
    this.entities = ol3d.entities
    this.view = this.map2d.getView()
    this.uavSource = uavSource // uav相关矢量图层数据源

    this.uavMap = uavMap // hash Map，用来存储uav相关信息
    this.trackLineMap = new Map() // 轨迹线
    this.targetLineMap = new Map() // 下一目标指引线(虚线)
    this.podViewCircleMap = new Map() // 吊舱视野位置
    this.podViewPointMap = new Map() // 吊舱视野点

    this.uavDomIdArr = [] // 存储无人机svg图标dom id
    this.imgSrcIndex = 0 // 当前新建飞机索引，循环创建不同飞机，关联 PLANE_COLOR_LIST
    this.popup = null // 自定义 popup overLay 层
    this.popupContent = '' // '<div class="popup-container"><div>名称：-- </div><div>机型：-- </div><div>状态：-- </div><div>高度：-- </div><div>空速：-- </div><div>地速：-- </div></div>'
    this.currentLatlng = []
  }

  /**
   * @desc: 添加（渲染）2d，3d无人机
   * @param {string} options.sn 无人机sn
   * @param {string} options.sessionId 无人机sessionId
   * @param {number} options.type 无人机类型 0-固定翼 1-旋翼 2-编队旋翼
   * @param {object} options.element 2d无人机渲染挂载dom元素
   * @param {number} options.yaw 2d无人机飞行过程中航向角 0 - 360
   * @param {array} options.latlng 经纬度集合 [116.234, 39.345] or [116.234, 39.345, 100]
   * @param {array} options.hpr 偏转、俯仰、横滚集合 [180, 30, 0]
   * @param {array} options.style { 'fillColor': 'rgba(0, 153, 255, 1)', 'strokeColor': 'rgba(255, 255, 255, 1)', 'strokeWidth': 2}
   * @use: this.addUav({sessionId: '', sn: 'HBRTEST202201061', type: 0, yaw: 0, latlng: [112.234, 35.345, 100], hpr: [90, 0, 0]})
   */
  addUav (options) {
    options = typeof options != undefined && options ? options : {}
    this.renderUav2D(options)
  }
  renderUav2D (options) { // 渲染2d无人机
    if (this.imgSrcIndex > 4) this.imgSrcIndex = 0 // 默认5个飞机颜色（../common/svg.js）
    let sessionId = options.sessionId
    let sn = options.sn || sessionId
    let planeImg = setLiveUavSvg(sessionId, this.imgSrcIndex, options.style)

    const uav2d = new OlOverlay({
      // rend3d: true, // 是否渲染3d 默认值为false
      sessionId: sessionId,
      id: sessionId, // 当前选中的飞机sn
      sn: sn,
      type: options.type,
      element: options.element || elementStr2Node(planeImg), // 飞机dom元素
      offset: [-23, -23] // 图标中心点位置
    })
    // 2d无人机姿态及位置
    const uav2dElement = uav2d.getElement()
    uav2dElement.style.transform = 'rotate(' + options.yaw + 'deg)'
    uav2d.setPosition(fromLonLat(options.latlng))
    this.map2d.addOverlay(uav2d)

    this.uavMap.set(sessionId, { 'uav2d': uav2d })

    // 渲染新飞机时，如果popup存在则
    if (this.popup) this.delPopupOverlay()
    setUavActiveSessionId(sessionId)

    // 选中的飞机添加click事件 后续实时更新可参考这个https://www.cnblogs.com/badaoliumangqizhi/p/15742637.html
    const that = this
    uav2dElement.onclick = function (e) {
      // 判断点击是否同一架，不是则显示飞机信息窗口，是则删除
      let id = this.getAttribute('id')
      if (options.popupData && options.popupData != '') {
        if (!that.popup) {
          that.popup = that.createUavPopupOverlay() // 自定义 popup overLay 层
          if (that.currentLatlng.length > 0) that.addPopupOverlay(that.currentLatlng, options.popupData)
          else that.addPopupOverlay(options.latlng, options.popupData)
        } else {
          if (id == getUavActiveSessionId()) { // 二次点击同一架飞机
            that.delPopupOverlay()
          } else { // 点击的非同一架飞机
            that.updatePopupOverlay(options.latlng, options.popupData)
          }
        }
      }
      setUavActiveSessionId(id) // 当前选中飞机的sessionId
      that.setUavClass(id)
    }

    // 3d
    this.renderUav3D(options, sessionId, uav2d)

    this.imgSrcIndex++
    this.uavDomIdArr.push(sessionId)
    this.setUavClass(sessionId)
  }
  renderUav3D (options, sessionId, uav2d) { // 渲染3d无人机
    const latlngArr = options.latlng || EPSG_4326_LATLNG
    const hprArr = options.hpr || HPR
    const position = Cesium.Cartesian3.fromDegrees(latlngArr[0], latlngArr[1], latlngArr[2] || 100)
    // console.log(position)
    const heading = Cesium.Math.toRadians(hprArr[0])
    const pitch = Cesium.Math.toRadians(hprArr[1])
    const roll = Cesium.Math.toRadians(hprArr[2])
    const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
    const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr)

    const uav3d = new Uav3d(this.entities, sessionId, options)
    uav3d.entity.position = position
    uav3d.entity.orientation = orientation

    this.uavMap.set(sessionId, { 'uav2d': uav2d, 'uav3d': uav3d })
  }

  /**
   * @desc: 同步删除2d、2d无人机
   * @param {string} sessionId 无人机sn
   */
  delUav (sessionId) {
    let currentUav = this.uavMap.get(sessionId)
    this.map2d.removeOverlay(currentUav.uav2d)
    this.entities.remove(currentUav.uav3d.entity)
    this.uavMap.delete(sessionId)

    // 同步删除航迹，目标引导线、吊舱位置等
    this.delUavTargetLine(sessionId)
    // this.delPodViewCircle(sessionId)
    this.delPodViewPoint(sessionId)
    this.delUavTrackLine(sessionId)
  }

  /**
   * @desc: 同步删除所有2d、3d无人机
   */
  delAllUavs () {
    // 删除所有2d无人机
    for (let value of this.uavMap.values()) {
      this.map2d.removeOverlay(value.uav2d)
    }
    // 删除所有3d无人机
    this.entities.removeAll()
    this.uavMap.clear()

    // 同步删除航迹，目标引导线、吊舱位置等
    this.delAllUavTargetLine()
    // this.delAllPodViewCircle()
    this.delAllPodViewPoint()
    this.delAllUavTrackLine()
  }

  /**
   * @desc: 更新无人机自身信息（位置、航向、hpr等）
   * @param {string} options.sn 无人机sn
   * @param {string} options.sessionId 无人机sessionId
   * @param {string} options.type 无人机类型
   * @param {number} options.num 无人机编号
   * @param {number} options.yaw 2d无人机飞行过程中航向角 0 - 360
   * @param {array} options.latlng 经纬度集合 [116.234, 39.345] or [116.234, 39.345, 100]
   * @param {array} options.hpr 偏转、俯仰、横滚集合 [180, 30, 0]
   * @param {array} options.podLatlng 吊舱视野中心点目标经纬度 [180, 30, 0]
   * @param {array} options.targetLatlng 下一个点位置 [180, 30, 0]
   * @param {string} options.airSpeed 空速
   * @param {string} options.groundSpeed 地速
   * @param {string} options.hspeed 垂直速
   * @param {array} options.voltage 电压
   * @use: this.updateUav({sn: 'HBRTEST202201061', yaw: 0, latlng: [112.234, 35.345, 100], hpr: [90, 0, 0]})
   */
  updateUav (options, isPlayback) {
    let hasUav = this.uavMap.has(options.sessionId)
    if (!hasUav) return false

    let currentUav2d = this.uavMap.get(options.sessionId).uav2d
    let uav2dElement = currentUav2d.getElement()
    uav2dElement.style.transform = 'rotate(' + options.yaw + 'deg)'
    currentUav2d.setPosition(transform(options.latlng, EPSG_4326, EPSG_3857))
    let latlng = [Number(options.latlng[0]), Number(options.latlng[1]), Number(options.latlng[2])] // 经纬度坐标

    // 3d
    let hprArr = [Number(options.hpr[0]), Number(options.hpr[1]), Number(options.hpr[2])]
    let position = Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2] || 80)
    let heading = Cesium.Math.toRadians(hprArr[0])
    let pitch = Cesium.Math.toRadians(hprArr[1])
    let roll = Cesium.Math.toRadians(hprArr[2])
    let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
    let orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr)

    let currentUav3d = this.uavMap.get(options.sessionId).uav3d
    let entity = currentUav3d.entity
    entity.position = position
    entity.orientation = orientation

    let mapType = getMapType()
    let isUavLocked = getUavLocked()
    let isPodLocked = getPodLocked()
    let uavActiveSessionId = getUavActiveSessionId()

    // 同步更新航迹，目标引导线、吊舱位置等
    if (!isPlayback) {
      // let targetLatlng = [Number(options.latlng[0]), Number(options.latlng[1]), Number(options.latlng[2])]
      // this.updateUavTargetLine(options.sessionId, latlng, targetLatlng)
      
      // 注： 直播详情返回数据暂无目标指引线
      if (options.podLatlng) {
        let podLatlng = [Number(options.podLatlng[0]), Number(options.podLatlng[1]), Number(options.podLatlng[2])]
        // this.updatePodViewCircle(options.sessionId, options.podLatlng)
        this.updatePodViewPoint(options.sessionId, podLatlng)
      }
      this.updaeUavTrackLine(options.sessionId, latlng)
    }

    if (options.sessionId == uavActiveSessionId) {
      // 更新飞机信息窗口
      this.currentLatlng = options.latlng
      if (options.popupData && options.popupData != '') this.updatePopupOverlay(options.latlng, options.popupData)
      // 跟随飞机
      let coordinate = fromLonLat(latlng)
      if (isUavLocked) {
        this.view.setCenter(coordinate) // 2d 锁定飞机时触发
        if (mapType != '2d') {
          // 3d飞机被锁定时触发
          var deltaLon = 0.20 * (Math.sin((options.yaw + 180) * Math.PI / 180))
          var deltaLat = 0.20 * (Math.cos((options.yaw + 180) * Math.PI / 180))
          var cameraPos3 = Cesium.Cartesian3.fromDegrees(latlng[0] + deltaLon * 180 / (Math.PI * Math.cos(latlng[1] * Math.PI / 180) * (6378137 + coordinate[2])), latlng[1] + deltaLat * 180 / (Math.PI * (6378137 + coordinate[2])), 3000) // 3000m 缩放比例15
          this.scene.camera.look(new Cesium.Cartesian3(0, 0, 1), Cesium.Math.toRadians(options.yaw))
          this.scene.camera.setView({
            destination: cameraPos3, // 设置位置,高度用tan角计算- Math.tan(PTZpitch * Math.PI / 180) * D
            orientation: orientation
          })
        }
      }

      // 3d 吊舱视角锁定
      if (isPodLocked) {
        if (mapType != '2d') {
          var deltaLon = 0.20 * (Math.sin((options.yaw + 180) * Math.PI / 180))
          var deltaLat = 0.20 * (Math.cos((options.yaw + 180) * Math.PI / 180))
          var cameraPos3 = Cesium.Cartesian3.fromDegrees(latlng[0] + deltaLon * 180 / (Math.PI * Math.cos(latlng[1] * Math.PI / 180) * (6378137 + coordinate[2])), latlng[1] + deltaLat * 180 / (Math.PI * (6378137 + coordinate[2])), latlng[2] - 0.15)
          this.scene.camera.look(new Cesium.Cartesian3(0, 0, 1), Cesium.Math.toRadians(options.yaw))
          this.scene.camera.setView({
            destination: cameraPos3, // 设置位置,高度用tan角计算- Math.tan(PTZpitch * Math.PI / 180) * D
            orientation: {
              heading: Cesium.Math.toRadians(hprArr[0]), // 方向
              pitch: Cesium.Math.toRadians(hprArr[1]), // 俯仰角度
              roll: 0
            }
          })
        }
      }
    }
  }

  /**
   * @desc: 获取指定无人机（切换飞机）
   * @param {string} sessionId 无人机sessionId
   */
  getUav (sessionId) {
    let currentUav = this.uavMap.get(sessionId)
    if (!currentUav) return false

    let coordinate = currentUav.uav2d.getPosition()
    let obj = { 'uav': currentUav, 'latlng': transform(coordinate, EPSG_3857, EPSG_4326) }
    this.setUavClass(sessionId)
    return obj
  }

  /**
   * @desc: 新增无人机飞向下一个目标点引导线集合
   * @param {Number} sessionId 当前无人机sessionId
   * @param {Array} currentLatlng 当前无人机经纬度
   * @param {Array} nextLatlng 下一个点经纬度
   */
  addUavTargetLine (sessionId, currentLatlng, nextLatlng) {
    if (currentLatlng[0] == 0 || currentLatlng[1] == 0 || nextLatlng[0] == 0 || nextLatlng[1] == 0) return false
    // 2d
    let style = { 'fillColor': 'rgba(19, 225, 130, 1)', 'strokeColor': 'rgba(0, 153, 255, 1)', 'strokeWidth': 2, 'dash': [10, 6] }
    let line = new Line(this.ol2d, this.ol3d, this.uavSource)
    line.addSingleLine(sessionId, currentLatlng, nextLatlng, true, style)
    let positions = []
    positions[0] = new Cesium.Cartesian3.fromDegrees(currentLatlng[0], currentLatlng[1], currentLatlng[2])
    positions[1] = new Cesium.Cartesian3.fromDegrees(nextLatlng[0], nextLatlng[1], nextLatlng[2])
    // 此处的sessionId被飞机占用，所以需要做区分
    let line3d = new Line3d(this.entities, 'targetLine_' + sessionId, style, true, false)
    line3d.positions = positions
    this.targetLineMap.set(sessionId, { 'item2d': line, 'item3d': line3d })
  }

  /**
   * @desc: 更新无人机目标引导线
   * @param {Number} sessionId
   * @param {*} currentLatlng
   * @param {*} nextLatlng
   * @return {*}
   * @use: 使用示例
   */
  updateUavTargetLine (sessionId, currentLatlng, nextLatlng) {
    if (currentLatlng[0] == 0 || currentLatlng[1] == 0 || nextLatlng[0] == 0 || nextLatlng[1] == 0) return false

    let hasTargetLine = this.targetLineMap.has(sessionId)
    if (!hasTargetLine) this.addUavTargetLine(sessionId, currentLatlng, nextLatlng)
    else {
      let currentTargetLine = this.targetLineMap.get(sessionId).item2d
      currentTargetLine.updateSingleLine(sessionId, currentLatlng, nextLatlng, this.targetLineMap)
    }
  }

  /**
   * @desc: 删除指定飞机目标引导线
   * @param {Number} sessionId
   */
  delUavTargetLine (sessionId) {
    removeFeatureAndDeleteHashMap(sessionId, this.targetLineMap, this.uavSource, this.entities)
  }

  /**
   * @desc: 删除所有飞机目标引导线
   */
  delAllUavTargetLine () {
    removeAllFeatureAndDeleteHashMap(this.targetLineMap, this.uavSource, this.entities)
  }

  /**
   * @desc: 新增无人机吊舱照射circle位置
   * @param {Number} sessionId
   * @param {Array} sessionId
   * @param {Number} radius
   * @return {*}
   * @use: 使用示例
   */
  addPodViewCircle (sessionId, latlng, radius) {
    // 2d
    let circle = new Circle(this.ol2d, this.uavSource)
    let style = { 'fillColor': 'rgba(0,102,104, 1)', 'strokeColor': 'green', 'strokeWidth': 2 }
    circle.addCircle2(sessionId, latlng, 4, 1, radius, style, false)
    // 3d
    let circle3d = new Circle3d(this.entities, 'podView_' + sessionId, 4, latlng, radius, null, false)
    this.podViewCircleMap.set(sessionId, { 'item2d': circle, 'item3d': circle3d })
  }

  /**
   * @desc: 更新吊舱视野circle位置
   * @param {Number} sessionId
   * @param {Array} latlng
   * @param {Number} radius
   * @param {Object} style
   */
  updatePodViewCircle (sessionId, latlng, radius = 160) {
    let hasPodView = this.podViewCircleMap.has(sessionId)
    if (!hasPodView) this.addPodViewCircle(sessionId, latlng, radius)
    else {
      let currentViewCircle = this.podViewCircleMap.get(sessionId).item2d
      let feature = currentViewCircle.feature
      let coordinate = fromLonLat(latlng)
      feature.getGeometry().setCenter(coordinate)

      // 3d (和uav的更新方式一样)
      let currentViewCircle3d = this.podViewCircleMap.get(sessionId).item3d
      let position = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2] || 80)
      currentViewCircle3d.position = position
    }
  }

  /**
   * @desc: 删除吊舱视野circle
   * @param {Number} sessionId
   */
  delPodViewCircle (sessionId) {
    removeFeatureAndDeleteHashMap(sessionId, this.podViewCircleMap, this.uavSource, this.entities)
  }

  /**
   * @desc: 删除所有吊舱视野circle
   */
  delAllPodViewCircle () {
    removeAllFeatureAndDeleteHashMap(this.podViewCircleMap, this.uavSource, this.entities)
  }

  /**
   * @desc: 无人机吊舱视野位置（图片）type = 5
   * @param {Number} sessionId
   * @param {Array} latlng
   * @return {*}
   * @use: 使用示例
   */
  addPodViewPoint (sessionId, latlng, image) {
    let currentPointMap = this.podViewPointMap.get(sessionId)
    if (currentPointMap == undefined) {
      image = image != '' && image ? image : UAV_POD_VIEW
      // 2d
      let point = new Point(this.ol2d, this.uavSource)
      point.addSinglePoint(sessionId, latlng, 5, 0, image, false, null, false)
      // 3d
      let position = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2] || 80)
      const point3d = new Point3d(this.entities, 'podViewPoint_' + sessionId, 'podViewPoint', '', '', image)
      point3d.position = position
      this.podViewPointMap.set(sessionId, { 'item2d': point, 'item3d': point3d })
    } else {
      this.updatePodViewPoint(sessionId, latlng)
    }
  }

  /**
   * @desc: 更新吊舱视野点
   * @param {Number} sessionId
   * @param {Array} latlng
   * @return {*}
   * @use: 使用示例
   */
  updatePodViewPoint (sessionId, latlng) {
    let hasPodView = this.podViewPointMap.has(sessionId)
    if (!hasPodView) this.addPodViewPoint(sessionId, latlng)
    else {
      let currentPoint = this.podViewPointMap.get(sessionId).item2d
      // 2d
      let feature = currentPoint.feature
      let coordinate = fromLonLat(latlng)
      if (feature != null) feature.getGeometry().setCoordinates(coordinate)
      // 3d
      let currentPoint3d = this.podViewPointMap.get(sessionId).item3d
      let position = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2] || 80)
      currentPoint3d.position = position
    }
  }

  /**
   * @desc: 删除吊舱视野点
   * @param {Number} sessionId
   */
  delPodViewPoint (sessionId) {
    removeFeatureAndDeleteHashMap(sessionId, this.podViewPointMap, this.uavSource, this.entities)
  }

  /**
   * @desc: 删除所有吊舱视野点
   */
  delAllPodViewPoint () {
    removeAllFeatureAndDeleteHashMap(this.podViewPointMap, this.uavSource, this.entities)
  }

  /**
   * @desc: 动态添加轨迹线
   * @param {Number} sessionId
   * @param {Array} latlng
   */
  addUavTrackLine (sessionId, latlng) {
    // 2d
    let line = new Line(this.ol2d, this.ol3d, this.uavSource)
    line.addTrackLine(sessionId, latlng)
    // 3d
    let positions = []
    positions[0] = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2])
    positions[1] = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2])
    let line3d = new Line3d(this.entities, 'trackLine_' + sessionId, null, false, false)
    line3d.positions = positions

    this.trackLineMap.set(sessionId, { 'item2d': line, 'item3d': line3d })
  }

  /**
   * @desc: 动态更新轨迹线
   * @param {Number} sessionId
   * @param {Array} latlng
   */
  updaeUavTrackLine (sessionId, latlng) {
    let hasTrackLine = this.trackLineMap.has(sessionId)
    if (!hasTrackLine) this.addUavTrackLine(sessionId, latlng)
    else {
      // 此处是 LineString 对象
      let coordinate = fromLonLat(latlng)
      let dynamicTrackLine = this.trackLineMap.get(sessionId).item2d.dynamicTrackLine
      let coordinateArr = dynamicTrackLine.getCoordinates()
      coordinateArr.push(coordinate)
      // 大于 2048 适当清除开头数据
      if (coordinateArr.length > DYNAMIC_TRACK_LINE_LENGTH) coordinateArr.splice(0, 1)
      dynamicTrackLine.setCoordinates(coordinateArr)

      // 3d （线特有的更新方式）
      let dynamicTrackLine3d = this.trackLineMap.get(sessionId).item3d
      let positions = dynamicTrackLine3d.positions
      if (positions.length > DYNAMIC_TRACK_LINE_LENGTH) positions.splice(0, 1)
      positions.push(new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2]))
    }
  }

  /**
   * @desc: 删除指定飞机轨迹线
   * @param {Number} sessionId
   */
  delUavTrackLine (sessionId) {
    removeFeatureAndDeleteHashMap(sessionId, this.trackLineMap, this.uavSource, this.entities)
  }

  /**
   * @desc: 删除所有飞机轨迹线
   */
  delAllUavTrackLine () {
    removeAllFeatureAndDeleteHashMap(this.trackLineMap, this.uavSource, this.entities)
  }

  /**
   * @desc: 无人机信息窗口
   * @param {Number} sessionId
   * @param {Array} latlng
   * @param {String} popupData Dom字符串
   * @return {*}
   * @use: 使用示例
   */
  addPopupOverlay (latlng, popupData = this.popupContent) {
    let element = this.popup.getElement()
    let coordinate = fromLonLat(latlng) // 投影坐标
    element.setAttribute('class', 'uav-popup-overlay show-uav-popup-overlay')
    element.innerHTML = popupData
    element.style.display = 'block' // 配合删除操作做的特殊处理
    this.map2d.addOverlay(this.popup)
    this.popup.setPosition(coordinate)
  }

  /**
   * @desc: 更新无人机信息窗口
   * @param {Array} latlng
   * @param {String} popupData Dom字符串
   * @return {*}
   * @use: 使用示例
   */
  updatePopupOverlay (latlng, popupData = this.popupContent) {
    if (this.popup) {
      // 同步更新popup（多机暂时存在问题 => 互相拉扯，id的事儿）
      let popupElement = this.popup.getElement()
      let coordinate = fromLonLat(latlng) // 投影坐标
      popupElement.innerHTML = popupData
      // popupElement.style.display = 'block' // 配合删除操作做的特殊处理
      this.popup.setPosition(coordinate)
    }
  }

  // 仅此一个窗口可直接删除，不做显示隐藏处理
  hidePopupOverlay () {
    if (this.popup) {
      let element = this.popup.getElement()
      element.setAttribute('class', 'uav-popup-overlay hide-uav-popup-overlay')
    }
  }

  delPopupOverlay () {
    this.map2d.removeOverlay(this.popup)
    this.popup = null
  }

  /**
   * @desc: 创建 overlay
   */
  createUavPopupOverlay () {
    let popup = document.createElement('div');
    popup.id = 'uavPopupOverlay';
    popup.style.cssText = 'background:rgba(0,0,0,0.5);color:white;border-radius:4px;padding:5px 10px;box-sizing: border-box;position:relative;font-size:12px;'
    document.body.appendChild(popup);

    return new OlOverlay({
      element: document.getElementById('uavPopupOverlay'),
      rend3d: true,
      autoPan: false, // 地图边缘是否自动移动地图使overlayer完全显示，true 高速移动偶尔会导致地图抖动
      autoPanMargin: 100,
      positioning: 'bottom-left',
      offset: [5, -5]
    })
  }

  /**
   * @desc: 设置飞机外围四个角是否显示及添加动画
   * @param {Number} id 飞机 sessionId
   */
  setUavClass (id) {
    if (this.uavDomIdArr.length <= 1) return false

    this.uavDomIdArr.forEach(item => {
      if (item == id) document.getElementById('svgOutPath_' + item).setAttribute('class', 'svg-uav-breath')
      else document.getElementById('svgOutPath_' + item).setAttribute('class', 'hide')
    })
  }
}

export default Uav
